﻿using System;
using System.Configuration;
using System.Net.Mail;
using System.Reflection;
using System.Windows.Forms;

using SalaryReport.Core;
using SalaryReport.Core.Excel;
using ExcelCell = SalaryReport.Core.Excel.ExcelCell;
using Timer = System.Windows.Forms.Timer;

namespace SalaryReport
{
    public partial class MainForm : Form
    {
        #region Private data

        private const string SUCCESS_LOG_TEMPLATE = "Salary for {0} was sent successfully.{1}";
        private const string ERROR_LOG_TEMPLATE = @"[User:{0}] {2} ERROR:{2}{1}{2}";

        private ExcelFile excelFile;
        private readonly ExcelSettings settings;
        private readonly Templates templates;

        private Timer timer;

        private SheetsCount sheetsCountForm;

        #endregion

        public MainForm()
        {
            InitializeComponent();
            Text += string.Format(" - version: {0}", typeof(MainForm).Assembly.GetName().Version);

            settings = new ExcelSettings();
            settings.OnNotify += (sender, args) => txtLog.AppendText(args.Message + Environment.NewLine);
            settings.Load();
            settings.DisplayOnElement(panelSettings);

            templates = new Templates();
            templates.Load();
            txtPaymentLetter.Text = templates.Data.PaymentTemplate;
            txtPrepaymentLetter.Text = templates.Data.PrePaymentTemplate;

            timer = new Timer();
            timer.Interval = int.Parse(ConfigurationManager.AppSettings["interval"]);
            timer.Tick += timer_Tick;
        }
        
        #region Controls events

        private delegate void LogDelegate(string log);

        private delegate void BarDelegate();

        private void UpdateBar()
        {
            progressBar.Value++;
            if (progressBar.Value == progressBar.Maximum)
            {
                timer.Stop();
                Worker.Current = 0;
                btnSendPayments.Enabled = btnSendPrepayments.Enabled = true;
                AddLog("Рассылка завершена");
            }
        }

        private void AddLog(string log)
        {
            txtLog.AppendText(log);
        }

        private void btnLoad_Click(object sender, EventArgs e)
        {
            var openDialog = new OpenFileDialog();
            if (openDialog.ShowDialog() == DialogResult.OK)
            {
                try
                {
                    excelFile = new ExcelFile(openDialog.FileName);
                    excelFile.OnNotify += (o, args) => AddLog(args.Message);

                    sheetsCountForm = new SheetsCount(excelFile.SheetsCount);
                    if (sheetsCountForm.ShowDialog() == DialogResult.OK)
                    {
                        var index = sheetsCountForm.SelectedIndex;
                        excelFile.Init(index);
                        
                        gbParams.Enabled = gbDelivery.Enabled = btnCheckTemplates.Enabled = true;
                        lblFile.Text = "OK";
                    }
                }
                catch (Exception ex)
                {
                    txtLog.AppendText(string.Format(ERROR_LOG_TEMPLATE, 0, ex.Message, Environment.NewLine));
                }
            }
        }

        private void btnSaveTemplates_Click(object sender, EventArgs e)
        {
            templates.Data.PaymentTemplate = txtPaymentLetter.Text;
            templates.Data.PrePaymentTemplate = txtPrepaymentLetter.Text;
            templates.Save();

            MessageBox.Show("Шаблоны сохранены успешно!");
        }

        private void btnSendPayments_Click(object sender, EventArgs e)
        {
            progressBar.Minimum = 0;
            progressBar.Value = 0;

            txtLog.Clear();
            btnSendPayments.Enabled = btnSendPrepayments.Enabled = false;

            this.SendLetters(txtPaymentLetter.Text);
        }

        private void btnSendPrepayments_Click(object sender, EventArgs e)
        {
            progressBar.Minimum = 0;
            progressBar.Value = 0;

            txtLog.Clear();
            btnSendPayments.Enabled = btnSendPrepayments.Enabled = false;

            this.SendLetters(txtPrepaymentLetter.Text);
        }

        private void btnSaveSettings_Click(object sender, EventArgs e)
        {
            settings.Save();

            MessageBox.Show("Настройки сохранены успешно!");
        }

        private void btnAddColumn_Click(object sender, EventArgs e)
        {
            var newColumn = new ExcelColumn();
            settings.Add(newColumn);
        }

        private void btnAddCell_Click(object sender, EventArgs e)
        {
            var newCell = new ExcelCell();
            settings.Add(newCell);
        }

        private void btnCheck_Click(object sender, EventArgs e)
        {
            var index = 0;
            if (!int.TryParse(txtIndex.Text, out index))
            {
                MessageBox.Show("Неверное значение индекса для проверки настроек!");
            }
            else
            {
                var items = excelFile.GetValuesForSettings(settings, index);
                var details = new DetailsForm(items);
                details.Show();
            }
        }

        private void btnCheckTemplates_Click(object sender, EventArgs e)
        {
            var index = 0;
            if (!int.TryParse(txtTmplIndex.Text, out index))
            {
                MessageBox.Show("Неверное значение индекса для проверки шаблонов!");
            }
            else
            {
                var items = excelFile.GetValuesForSettings(settings, index);
                
                var paymentInfo = new SalaryInfo(items, txtPaymentLetter.Text);
                MessageBox.Show(paymentInfo.ParseTemplate(), "Зарплата");

                var prepaymentInfo = new SalaryInfo(items, txtPrepaymentLetter.Text);
                MessageBox.Show(prepaymentInfo.ParseTemplate(), "Аванс");
            }
        }

        #endregion

        #region Sending letters

        private void SendLetters(string template)
        {
            int start = 0, end = 0;

            if (!int.TryParse(txtStart.Text, out start) || !int.TryParse(txtEnd.Text, out end))
            {
                MessageBox.Show("Заполните стартовый и конечный индексы для рассылки!!!");
            }
            else
            {
                if (start > end)
                {
                    MessageBox.Show("Конечный индекс не может быть меньше начального! Заполните индексы для рассылки корректно!");
                }
                else
                {
                    progressBar.Maximum = end - start + 1;

                    Worker.Reports.Clear();

                    for (var i = start; i <= end; i++)
                    {
                        var items = excelFile.GetValuesForSettings(settings, i);

                        var info = new SalaryInfo(items, template);

                        Worker.Reports.Add(info);
                    }
                    timer.Start();
                }
            }
        }

        private void timer_Tick(object sender, EventArgs args)
        {
            var info = Worker.Next;

            try
            {
                var smtpClient = new SmtpClient();
                var msg = info.ParseTemplate();
                var mailMsg = new MailMessage(ConfigurationManager.AppSettings["from"], info.GetEmail(), ConfigurationManager.AppSettings["subject"], msg);
                smtpClient.Send(mailMsg);
                AddLog(string.Format(SUCCESS_LOG_TEMPLATE, info.GetEmail(), Environment.NewLine));
            }
            catch (Exception e)
            {
                AddLog(string.Format(ERROR_LOG_TEMPLATE, info.GetEmail(), e.Message, Environment.NewLine));
            }

            UpdateBar();
        }

        #endregion
    }
}
